include ../build/Makefile-vars

# NOTE: original upstream is https://netlib.org/f2c/, and that does still get maintained.
# However, the maintenance is minimal, I don't trust the host, and MOST IMPORTANTLY, it is
# impossible to get a *specific known point in time version*.  A fundamental rule of
# downloading sources is that they have to be versioned and all versions stay available.

# See https://github.com/sagemathinc/f2c/releases
VERSION=2022-09-09

URL = https://github.com/sagemathinc/f2c/archive/refs/tags/${VERSION}.tar.gz

TARBALL = ${UPSTREAM}/f2c-${VERSION}.tar.gz

all: native wasm

include ../build/Makefile-rules

###########
# NATIVE
###########

${DIST_NATIVE}/.built: ${DIST_NATIVE}/bin/f2c ${DIST_NATIVE}/lib/libf2c.a ${DIST_NATIVE}/include/f2c.h
	touch ${DIST_NATIVE}/.built

# NOTES:
#   - The zig built f2c crashes if you use -O0, but NOT with -O2!
${DIST_NATIVE}/bin/f2c: ${BUILD_NATIVE}/.build
	cd ../build && make zig
	cd ${BUILD_NATIVE}/f2c \
		&& make CC="zig cc ${ZIG_NATIVE_CFLAGS_GNU} " CFLAGS="-O2" -j8 -f makefile.u \
		&& mkdir -p ${DIST_NATIVE}/bin \
		&& cp f2c ${DIST_NATIVE}/bin

${DIST_NATIVE}/lib/libf2c.a: ${BUILD_NATIVE}/.build
	cd ${BUILD_NATIVE}/libf2c \
		&& make CC="zig cc ${ZIG_NATIVE_CFLAGS_GNU} " CFLAGS="-O2" -j8 -f makefile.u \
		&& mkdir -p ${DIST_NATIVE}/lib \
		&& cp libf2c.a ${DIST_NATIVE}/lib

${DIST_NATIVE}/include/f2c.h: ${DIST_NATIVE}/bin/f2c
	mkdir -p ${DIST_NATIVE}/include/
	cp ${BUILD_NATIVE}/f2c/f2c.h ${DIST_NATIVE}/include/

# TODO/WARNING: The test actually fails with "zig cc" right now in numerous ways with
# malloc crashes and segfaults.
# These are clearly due to a bunch of bugs in zig cc that I haven't hit elsewhere.
# Hopefully these will go away someday when we update to a newer version of zig.
# We test with gcc below, which works.
# That said, this does NOT matter, since we only need to use the result of f2c
# on WebAssembly, and there fully using zig completely works fine below.
test-native: native
	rm -rf ${BUILD_NATIVE}/test
	mkdir -p ${BUILD_NATIVE}/test
	cp src/hello.f ${BUILD_NATIVE}/test
	cd ${BUILD_NATIVE}/test \
		&& ${DIST_NATIVE}/bin/f2c hello.f \
		&& gcc hello.c -w -o hello -I${DIST_NATIVE}/include -lf2c -L${DIST_NATIVE}/lib \
		&& ./hello | grep Hello   # would fail if "Hello" not in output.

###########
# WASM
###########

${DIST_WASM}/.built: ${DIST_WASM}/lib/libf2c.a ${DIST_WASM}/include/f2c.h
	touch ${DIST_WASM}/.built

${BUILD_WASM}/.patched: ${BUILD_WASM}/.build
	cd ${BUILD_WASM}/libf2c && cat ${CWD}/src/00-wasm-makefile-ld.patch | patch -p2
	touch ${BUILD_WASM}/.patched

# The file arith.h is autogenerated by creating and running a C program.
# It works if we build it directly using zcc, but NOT using cowasm-cc (our -fPIC variant),
# which is why we run make twice below.
${DIST_WASM}/lib/libf2c.a: ${BUILD_WASM}/.patched
	cd ../build && make zig
	cd ${BUILD_WASM}/libf2c \
		&& make CC="zcc" CFLAGS="-Oz" arith.h -f makefile.u \
		&& make CC="cowasm-cc" CFLAGS="-Oz"  -f makefile.u  -j8 \
		&& mkdir -p ${DIST_WASM}/lib \
		&& cp libf2c.a ${DIST_WASM}/lib

${DIST_WASM}/include/f2c.h: ${DIST_WASM}/lib/libf2c.a
	mkdir -p ${DIST_WASM}/include/
	cp ${BUILD_WASM}/f2c/f2c.h ${DIST_WASM}/include/
	# with clang5 the f2c's main ends up as __main_argc_argv, and standalone
	# f2c has main_ which doesn't work.  This also avoids the fake signal code.
	echo '#define main_ main' >>  ${DIST_WASM}/include/f2c.h

test-wasm: wasm native node_modules
	cd ../build && make zig
	rm -rf ${BUILD_WASM}/test
	mkdir -p ${BUILD_WASM}/test
	cp src/hello.f ${BUILD_WASM}/test
	cd ${BUILD_WASM}/test \
		&& ${DIST_NATIVE}/bin/f2c hello.f \
		&& zcc hello.c -o hello -lc -I${DIST_WASM}/include -lf2c -L${DIST_WASM}/lib \
		&& ./hello | grep "Hello, world!"   # would fail if "Hello" not in output.

# only care about wasm test passing
test: test-wasm
